﻿using System;
using System.Linq;
using System.Reflection;
using Dqaqs.Common;
using log4net;

namespace Dqaqs.Host
{
	public class RemoteProxy : MarshalByRefObject
	{
		private readonly ILog _log = LogManager.GetLogger(typeof(DqaqsHost));

		static internal Tuple<AppDomain, RemoteProxy> Start()
		{
			var appDomain = AppDomain.CreateDomain(Assembly.GetExecutingAssembly().FullName);
			var proxy = (RemoteProxy) appDomain.CreateInstanceAndUnwrap(
				Assembly.GetExecutingAssembly().FullName,
				typeof (RemoteProxy).FullName);
			return Tuple.Create(appDomain, proxy);
		}

		public string[][,] LoadAndRunAssembly(string name, string[] pars)
		{
			ArgumentCheck.NotNullOrEmpty(name, "name");
			try
			{
				var ass = Assembly.LoadFrom(name);
				var objType = ass.GetTypes().FirstOrDefault(t => t.GetInterface("IDataAlgorithmImplementer") != null);
				var obj = (IDataAlgorithmImplementer)Activator.CreateInstance(objType);
				return obj.Main(pars);
			}
			catch (Exception ex)
			{
				_log.Error(string.Format("Error happened while loading the assembly {0}.", name), ex);
				throw;
			}
		}

		public static string[][,] ExecuteAlgorithmImplenter(string assName, string[] args)
		{
			var proxy = Start();
			var rv = proxy.Item2.LoadAndRunAssembly(assName, args);
			AppDomain.Unload(proxy.Item1);
			return rv;
		}
	}
}
